package cn.smarttoo.web;


import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

@Controller
public class ElasearchController {
    @Autowired
    private TransportClient client;


 /*   @PostMapping("create/index")
    @ResponseBody
    public ResponseEntity createIndex(@RequestParam(name = "index")String index,@RequestParam(name = "type")String type){


    }*/

    /**
     * 通过ID查询数据
     * @param id
     * @return
     */
    @GetMapping("/get/book/novel")
    @ResponseBody
    public ResponseEntity get(@RequestParam(name="id",defaultValue = "")String id){
        GetResponse result = this.client.prepareGet("book", "novel", id)
                .get();

        if(!result.isExists()){
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        }

        return new ResponseEntity(result.getSource(), HttpStatus.OK);
    }


    /**
     * 添加数据
     * @param title
     * @param author
     * @param wordCount
     * @param publishDate
     * @return
     */
    @PostMapping("add/book/novel")
    @ResponseBody
    public ResponseEntity add(
            @RequestParam(name="title")String title,
            @RequestParam(name = "author")String author,
            @RequestParam(name = "word_count")int wordCount,
            @RequestParam(name = "publish_date")
                    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
                    Date publishDate
    ){
        try{
            XContentBuilder context = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("title", title)
                    .field("author", author)
                    .field("word_count", wordCount)
                    .field("publish_date", publishDate.getTime())
                    .endObject();
            IndexResponse result = this.client.prepareIndex("book", "novel")
                    .setSource(context)
                    .get();

            return new ResponseEntity(result.getId(),HttpStatus.OK);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }


    }

    /**
     * 删除接口
     * @param id
     * @return
     */
    @GetMapping("delete/book/novel")
    @ResponseBody
    public ResponseEntity delete (@RequestParam(name = "id")String id){
        DeleteResponse result = this.client.prepareDelete("book","novel",id)
                .get();

        return new ResponseEntity(result.getResult().toString(),HttpStatus.OK);
    }

    /**
     * 更新接口
     * @param id
     * @param title
     * @param author
     * @return
     */
    @PutMapping("update/book/novel")
    @ResponseBody
    public ResponseEntity update(
            @RequestParam(name = "id")String id,
            @RequestParam(name = "title",required = false)String title,
            @RequestParam(name = "author",required = false)String author
    ){
        UpdateRequest update = new UpdateRequest("book","novel",id);
        try{
            XContentBuilder builder = XContentFactory.jsonBuilder().startObject();
            if (title!=null){
                builder.field("title",title);
            }
            if (author!=null){
                builder.field("author",author);
            }
            builder.endObject();
            update.doc(builder);

        }catch (Exception e){
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }

        try {
            UpdateResponse result = this.client.update(update).get();
            return new ResponseEntity(result.getGetResult().toString(),HttpStatus.OK);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        } catch (ExecutionException e) {
            e.printStackTrace();
            return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
        }


    }

    @PostMapping("query/book/novel")
    @ResponseBody
    public ResponseEntity query(
            @RequestParam(name = "author",required = false)String author,
            @RequestParam(name = "title",required = false)String title,
            @RequestParam(name = "gt_word_count",defaultValue = "0") int gtWordCount,
            @RequestParam(name = "lt_word_count",required = false) Integer ltWordCount
    ){

        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (author!=null){
            boolQuery.must(QueryBuilders.matchQuery("author",author));
        }
        if (title!=null){
            boolQuery.must(QueryBuilders.matchQuery("title",title));
        }

        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("word_count")
                .from(gtWordCount);
        if (ltWordCount!=null&&ltWordCount>0){
            rangeQuery.to(ltWordCount);
        }
        boolQuery.filter(rangeQuery);

        SearchRequestBuilder builder = this.client.prepareSearch("book")
                .setTypes("novel")
                .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                .setQuery(boolQuery)
                .setFrom(0)
                .setSize(10);

        System.out.println(builder);

        SearchResponse response = builder.get();

        List<Map<String,Object>> result = new ArrayList<>();

        response.getHits().forEach(item->{
            result.add(item.getSource());
        });



        return new ResponseEntity(result,HttpStatus.OK);

    }



}
